package com.color.admin.system.servie.impl;


import com.color.admin.common.core.constant.Constant;
import com.color.admin.common.core.exception.BaseException;
import com.color.admin.common.core.page.PageRequest;
import com.color.admin.common.core.page.PageResponse;
import com.color.admin.common.core.utils.tools.QueryHelp;
import com.color.admin.common.core.utils.web.StringUtils;
import com.color.admin.system.entity.SysDictDetail;
import com.color.admin.system.entity.query.DictQueryCriteria;
import com.color.admin.system.entity.vo.dict.DictDetailVo;
import com.color.admin.system.repository.DictDetailRepository;
import com.color.admin.system.servie.DictDetailService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author HaiQiu
 * @date 2022/1/18
 */
@Service
public class DictDetailServiceImpl implements DictDetailService {

    @Autowired
    private DictDetailRepository dictDetailRepository;


    @Override
    public void save(SysDictDetail sysDictDetail) {
        checkDictId(sysDictDetail);
        sysDictDetail.setCreateTime(new Date());
        sysDictDetail.setUpdateTime(new Date());
        SysDictDetail save = dictDetailRepository.save(sysDictDetail);
        if (ObjectUtils.isEmpty(save)){
            throw new BaseException(Constant.INSERT_FAIL);
        }
    }

    @Override
    public void update(SysDictDetail sysDictDetail) {
        checkDictId(sysDictDetail);
        SysDictDetail dictDetail = dictDetailRepository.findById(sysDictDetail.getId()).orElseGet(SysDictDetail::new);
        if (ObjectUtils.isEmpty(dictDetail)){
            throw new BaseException(Constant.DATA_EXITS);
        }
        dictDetail.setDict(sysDictDetail.getDict());
        dictDetail.setUpdateTime(new Date());
        dictDetail.setLabel(sysDictDetail.getLabel());
        dictDetail.setValue(sysDictDetail.getValue());
        dictDetail.setActive(sysDictDetail.getActive());
        dictDetail.setSort(sysDictDetail.getSort());
        SysDictDetail save = dictDetailRepository.save(dictDetail);
        if (ObjectUtils.isEmpty(save)){
            throw new BaseException(Constant.UPDATE_FAIL);
        }
    }

    /**
     * 校验是否选中父级目录
     * @param sysDictDetail 参数
     */
    private void checkDictId(SysDictDetail sysDictDetail) {
        if (ObjectUtils.isEmpty(sysDictDetail) || ObjectUtils.isEmpty(sysDictDetail.getDict())
                || StringUtils.isBlank(sysDictDetail.getDict().getId())){
            throw new BaseException("未选择父级字典目录");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)){
            throw new BaseException(Constant.ID_EXITS);
        }
        if (dictDetailRepository.deleteAllByIdIn(ids)==0){
            throw new BaseException(Constant.DELETE_FAIL);
        }
    }

    @Override
    public SysDictDetail get(String dictDetailId) {
        SysDictDetail dictDetail = dictDetailRepository.findById(dictDetailId).orElseGet(SysDictDetail::new);
        return dictDetail;
    }

    @Override
    public PageResponse<DictDetailVo> list(PageRequest<DictQueryCriteria> request) {
        DictQueryCriteria criteria = request.getParams();

        Pageable pageable = org.springframework.data.domain.PageRequest.of(request.getNum(),
                request.getPageSize(), Sort.by("sort"));

        Page<SysDictDetail> details = dictDetailRepository.findAll((root, query, criteriaBuilder) ->
                QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);

        Page<DictDetailVo> detailVos = details.map(detail -> {
            DictDetailVo vo = new DictDetailVo();
            BeanUtils.copyProperties(detail, vo);
            vo.setDictId(detail.getDict().getId());
            return vo;
        });

        PageResponse<DictDetailVo> response = new PageResponse<>();

        response.setTotalElements(detailVos.getTotalElements());
        response.setPageIndex(request.getPageIndex());
        response.setPageSize(request.getPageSize());
        response.setData(detailVos.getContent());
        return response;
    }

    @Override
    public SysDictDetail saveRes(SysDictDetail sysDictDetail) {
        checkDictId(sysDictDetail);
        sysDictDetail.setCreateTime(new Date());
        sysDictDetail.setUpdateTime(new Date());
        SysDictDetail save = dictDetailRepository.save(sysDictDetail);
        if (ObjectUtils.isEmpty(save)){
            throw new BaseException(Constant.INSERT_FAIL);
        }
        return save;
    }

    @Override
    public SysDictDetail updateRes(SysDictDetail sysDictDetail) {
        checkDictId(sysDictDetail);
        SysDictDetail dictDetail = dictDetailRepository.findById(sysDictDetail.getId()).orElseGet(SysDictDetail::new);
        if (ObjectUtils.isEmpty(dictDetail)){
            throw new BaseException(Constant.DATA_EXITS);
        }
        dictDetail.setDict(sysDictDetail.getDict());
        dictDetail.setUpdateTime(new Date());
        dictDetail.setLabel(sysDictDetail.getLabel());
        dictDetail.setValue(sysDictDetail.getValue());
        dictDetail.setActive(sysDictDetail.getActive());
        dictDetail.setSort(sysDictDetail.getSort());
        SysDictDetail save = dictDetailRepository.save(dictDetail);
        if (ObjectUtils.isEmpty(save)){
            throw new BaseException(Constant.UPDATE_FAIL);
        }
        return save;
    }

    @Override
    public List<DictDetailVo> getByCode(String code) {
        List<SysDictDetail> details = new ArrayList<>();
        if (StringUtils.isBlank(code)){
            details = dictDetailRepository.findAll();
        }else {
            DictQueryCriteria criteria = new DictQueryCriteria();
            criteria.setCode(code);
            details = dictDetailRepository.findAll((root, query, criteriaBuilder) ->
                    QueryHelp.getPredicate(root, criteria, criteriaBuilder));
        }
        List<DictDetailVo> detailVos = details.stream().map(dictDetail -> {
            DictDetailVo vo = new DictDetailVo();
            BeanUtils.copyProperties(dictDetail, vo);
            vo.setDictId(dictDetail.getDict().getId());
            vo.setCode(dictDetail.getDict().getCode());
            return vo;
        }).collect(Collectors.toList());
        return detailVos;
    }
}
